package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.dto.CommentDto;
import com.heima.comment.dto.CommentLikeDto;
import com.heima.comment.dto.CommentSaveDto;
import com.heima.comment.dto.UpdateArticleMessage;
import com.heima.comment.entity.ApComment;
import com.heima.comment.entity.ApCommentLike;
import com.heima.comment.entity.ApUser;
import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.ICommentService;
import com.heima.comment.vo.ApCommentVo;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.AppThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class CommentServiceImpl implements ICommentService {
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private GreenTextScan greenTextScan;


    /**
     * 发表评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //判断用户是否登录
        //获取线程里的user
        User user = AppThreadLocalUtil.get();
        if (user == null || (!StringUtils.isEmpty(user.getUserId())&&user.getUserId().equals(0))){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //判断评论内容是否大于140字
        if (dto == null ||dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        // TODO: 2022/6/28  阿里云内容安全审核评论
        Boolean flag = checkText(dto.getContent());
        if (!flag) return ResponseResult.errorResult(500,"评论内容违规");
        //评论对象
        ApComment comment = new ApComment();
        comment.setAuthorId(user.getUserId());
        //远程调用feign根据user_id查询出用户名
        ResponseResult<ApUser> result = userFeign.getById(user.getUserId());
        ApUser apUser = result.getData();
        comment.setAuthorName(apUser.getName());
        comment.setEntryId(dto.getArticleId());
        comment.setChannelId(dto.getChannelId());
        comment.setType(0);
        comment.setContent(dto.getContent());
        comment.setLikes(0);
        comment.setReply(0);
        comment.setFlag(0);
        comment.setCreatedTime(new Date());
        mongoTemplate.save(comment);

        //Kafka发送消息到主题article_behavior
        sendMessage(dto);

        return ResponseResult.okResult();
    }

    /**
     * 加载评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentDto dto) {
        //判断用户是否登录
        //获取线程里的user
        User user = AppThreadLocalUtil.get();
        if (user == null || (!StringUtils.isEmpty(user.getUserId())&&user.getUserId().equals(0))){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //给一个默认的每页展示大小
        if (dto.getSize()==null || dto.getSize()<=0 ||dto.getSize()>50){
            dto.setSize(10);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("entryId").is(dto.getArticleId()));
        Pageable page = PageRequest.of(0,dto.getSize(), Sort.Direction.DESC,"createdTime");
        query.with(page);
        List<ApComment> comments = mongoTemplate.find(query, ApComment.class);

        // 登录用户需要查看当前返回的列表中是否已经有点赞记录
        List<String> commentIds = new ArrayList<>();
        for (ApComment comment : comments) {
            commentIds.add(comment.getId());
        }
        Query likeQuery = new Query();
        //筛选当前用户的点赞评论
        likeQuery.addCriteria(Criteria.where("authorId").is(user.getUserId()));
        //筛选当前页当前用户的点赞评论
        likeQuery.addCriteria(Criteria.where("commentId").in(commentIds));
        //筛选是点赞而不是撤销点赞的记录
        likeQuery.addCriteria(Criteria.where("operation").is(0));
        List<ApCommentLike> likes = mongoTemplate.find(likeQuery, ApCommentLike.class);

        //遍历当前页点赞的评论,取出评论id,封装成集合
        List<String> likeCommentsIds = new ArrayList<>();
        for (ApCommentLike like : likes) {
            likeCommentsIds.add(like.getCommentId());
        }
        //创建前端需要的vo对象
        List<ApCommentVo> vos = new ArrayList<>();
        for (ApComment comment : comments) {
            ApCommentVo apCommentVo = new ApCommentVo();
            BeanUtils.copyProperties(comment,apCommentVo);
            //默认没有点赞,设置operation为1
            apCommentVo.setOperation(1);
            //当前页评论里有当前用户点赞的评论,则设置为0
            if (likeCommentsIds.contains(comment.getId())){
                apCommentVo.setOperation(0);
            }
            vos.add(apCommentVo);
        }
        return ResponseResult.okResult(vos);
    }

    /**
     * 点赞某一条评论
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //判断用户是否登录
        //获取线程里的user
        User user = AppThreadLocalUtil.get();
        if (user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //创建点赞记录
        ApCommentLike like = new ApCommentLike();
        like.setAuthorId(user.getUserId());
        like.setCommentId(dto.getCommentId());
        like.setOperation(dto.getOperation());
        //根据当前用户id和评论id查询是否已有点赞记录
        Query query = new Query();
        query.addCriteria(Criteria.where("authorId").is(user.getUserId()))
                .addCriteria(Criteria.where("commentId").is(dto.getCommentId()));
        ApCommentLike one = mongoTemplate.findOne(query, ApCommentLike.class);
        if (one == null){
            //没有点赞记录,新增点赞记录
            mongoTemplate.save(like);
            //更新评论的点赞数+1
            Query commentQuery = new Query();
            commentQuery.addCriteria(Criteria.where("_id").is(dto.getCommentId()));
            Update update = new Update();
            update.inc("likes");
            mongoTemplate.updateFirst(commentQuery,update,ApComment.class);
        }else{
            //有过点赞记录
            if (dto.getOperation() != one.getOperation()){
                //判断当前是点赞还是取消点赞
                int add = 1;
                //修改状态
                one.setOperation(dto.getOperation());
                mongoTemplate.save(one);
                if (dto.getOperation() == 1){
                    //取消点赞
                    add = -1;
                }
                //更新当前评论的总点赞数量
                Query commentQuery = new Query();
                commentQuery.addCriteria(Criteria.where("_id").is(dto.getCommentId()));
                System.out.println("--------->"+dto.getCommentId());
                Update update = new Update();
                update.inc("likes",add);
                mongoTemplate.updateFirst(commentQuery,update,ApComment.class);
            }
        }
        return ResponseResult.okResult();
    }

    /**
     * 内容审查
     * @param content
     * @return
     */
    private Boolean checkText(String content) {
        boolean flag = true;
        try {
            Map map = greenTextScan.greenTextScan(content);
            //检测后返回的结果判断
            String suggestion = (String) map.get("suggestion");
            if ("pass".equals(suggestion)) {
                //审核通过
                flag = true;
            }else {
                flag =false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    @Value("${topic.comment_behavior}")
    private String commentTopic;
    /**
     * 发消息到Kafka
     * @param dto
     */
    private void sendMessage(CommentSaveDto dto) {
        UpdateArticleMessage message = new UpdateArticleMessage();
        message.setType(2);
        message.setArticleId(dto.getArticleId());
        message.setAdd(1);
        String json = JSON.toJSONString(message);
        kafkaTemplate.send(commentTopic,json);
    }
}
